package mya.mes.mdc.internal.ui;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.sun.prism.PixelFormat;
import mya.common.excel.bean.BeanExcel;
import mya.common.excel.bean.ExcelRowData;
import mya.common.excel.config.ExcelConfig;
import mya.common.excel.config.SheetConfig;
import mya.common.jaxrs.result.AddResult;
import mya.common.jpa.context.AbstractLogic;
import mya.common.jpa.context.ServiceContext;
import mya.common.model.constants.DataType;
import mya.common.model.json.JsonHelper;
import mya.common.service.gate.file.FileItemDto;
import mya.common.service.upload.UploadService;
import mya.common.service.upload.impl.UploadServiceImpl;
import mya.mes.mdc.local.mongodb.FilterDto;
import mya.mes.mdc.local.mongodb.MongoDbService;
import mya.mes.mdc.model.mdc.MdcTagDef;
import mya.mes.mdc.mongodb.MongoDbServiceImpl;
import mya.mes.mdc.queries.mdc.MdcTagDefQuery;
import org.bson.Document;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.io.File;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Path("/{tenantId}/{loginId}/mdcdata/ui/")
public class MdcDataUi {

    @PathParam("tenantId")
    private String tenantId;

    @PathParam("loginId")
    private Long loginId;

    @POST
    @Path("uploadExcel")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public AddResult uploadExcel(Long id) {

        final List<ExcelRowData<MdcTagDef>> list;

        try {

            UploadService service = new UploadServiceImpl();

            FileItemDto fileItem = service.getUploadTemp(id);

            java.nio.file.Path srcPath = Paths.get(fileItem.getTmpFileName());

            File file = srcPath.toFile();

            ExcelConfig excelConfig = new ExcelConfig();

            SheetConfig sheetConfig = excelConfig.config(0, 1, null);

            sheetConfig.col(0, DataType.DT_STRING, "tagNo");
            sheetConfig.col(2, DataType.DT_STRING, "dataType");
            sheetConfig.col(15, DataType.DT_STRING, "tagName");

            BeanExcel<MdcTagDef> beanExcel = new BeanExcel<>(MdcTagDef.class);
            list = beanExcel.parse(file, excelConfig);
        } catch (Exception e) {
            return AddResult.fail(e);
        }

        AbstractLogic logic = new AbstractLogic(tenantId, loginId) {
            @Override
            protected Object process(ServiceContext serviceContext) throws Exception {

                List<MdcTagDef> defList = MdcTagDefQuery.queryAll(serviceContext);

                HashMap map = new HashMap();

                for (MdcTagDef def : defList) {

                    map.put(def.getTagNo(), def);
                }

                String tagNo = null;
                String tagName = null;
                Integer index = null;
                String type = null;

                for (ExcelRowData<MdcTagDef> excelRowData : list) {

                    MdcTagDef mdcTagDef = excelRowData.data;
                    tagNo = mdcTagDef.getTagNo();
                    tagName = mdcTagDef.getTagName();
                    index = excelRowData.rowNum;
                    type = mdcTagDef.getDataType();

                    if (tagNo != null) {

                        if (map.get(tagNo) != null) {

                            MdcTagDef oldTag = (MdcTagDef) map.get(tagNo);
                            oldTag.setTagName(tagName);
                            oldTag.setSeqIndex(index);
                            oldTag.setDataType(type);
                            serviceContext.em.persist(oldTag);

                        } else {

                            MdcTagDef newTag = new MdcTagDef();
                            newTag.setActive(true);
                            newTag.setTagName(tagName);
                            newTag.setSeqIndex(index);
                            newTag.setDataType(type);
                            newTag.setTagNo(tagNo);
                            newTag.setChartShow(false);
                            serviceContext.em.persist(newTag);
                        }

                    } else {

                        continue;
                    }
                }
                return null;
            }
        };

        return AddResult.result(logic);
    }


    @POST
    @Path("queryMdcChart/")
    @Produces("application/json")
    public AddResult queryMdcChart(JsonNode node) {

        List<String> tagNoList = new ArrayList<>();
        List<FilterDto> dtoList = new ArrayList<>();

        if (node != null) {

            JsonNode tagNoNode = node.get("tagNo");

            for (JsonNode tagNoItem : tagNoNode) {

                String tn = tagNoItem.asText();

                tagNoList.add(tn);
            }

            JsonNode filterNode = node.get("filter");

            for (JsonNode filterItem : filterNode) {

                FilterDto dto = new FilterDto();

                dto.propertyName = filterItem.get("propertyName").asText();
                dto.operator = filterItem.get("operator").asText();
                if (dto.propertyName.equals("_id")) {
                    dto.longValue = filterItem.get("value").longValue();
                } else {
                    dto.value = filterItem.get("value").asText();
                }

                dtoList.add(dto);
            }
        }

        try {
            List<JsonNode> list = new ArrayList<>();

            MongoDbService service = new MongoDbServiceImpl();

            List<Document> dataList = service.queryTagData(tagNoList, dtoList, null);

            return AddResult.ok(dataList);

//            for (Document document : dataList) {
//
//                String json = document.toJson();
//                ObjectNode jn = (ObjectNode) JsonHelper.objectMapper.readTree(json);
//                jn.remove("_id");
//                jn.put("objectId", document.getLong("_id").longValue());
//                list.add(jn);
//            }
//
//            return AddResult.ok(list);

        } catch (Exception e) {
            return AddResult.fail(e.getMessage());
        }
    }
}
